package com.lifeverse.service;

import com.lifeverse.entity.LearningExperience;
import com.lifeverse.entity.LifeEntity;
import com.lifeverse.entity.enums.ExperienceType;
import com.lifeverse.entity.enums.LearningOutcome;
import com.lifeverse.repository.LearningExperienceRepository;
import com.lifeverse.util.JsonUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 经验学习服务
 * 负责生命体的经验学习机制
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class ExperienceLearningService {

    private final LearningExperienceRepository learningExperienceRepository;
    private final JsonUtils jsonUtils;

    /**
     * 记录学习经验
     */
    @Transactional
    public LearningExperience recordLearningExperience(Long lifeEntityId, Map<String, Object> experienceData) {
        log.info("为生命体 {} 记录学习经验", lifeEntityId);
        
        try {
            LearningExperience experience = new LearningExperience();
            experience.setLifeEntityId(lifeEntityId);
            
            // 从经验数据中提取信息
            experience.setExperienceType(parseExperienceType(experienceData));
            experience.setTitle((String) experienceData.getOrDefault("title", "未命名经验"));
            experience.setDescription((String) experienceData.get("description"));
            experience.setLearningContent((String) experienceData.get("learning_content"));
            experience.setContext((String) experienceData.get("context"));
            
            // 设置学习结果和效率
            experience.setOutcome(parseLearningOutcome(experienceData));
            experience.setEfficiency(parseDouble(experienceData, "efficiency", 0.5));
            experience.setRetentionRate(parseDouble(experienceData, "retention_rate", 0.7));
            experience.setApplicationSuccessRate(parseDouble(experienceData, "application_success_rate", 0.6));
            
            // 设置难度和重要性
            experience.setDifficultyLevel(parseInt(experienceData, "difficulty_level", 5));
            experience.setImportanceScore(parseDouble(experienceData, "importance_score", 0.5));
            
            // 设置时间信息
            experience.setStartedAt(parseDateTime(experienceData, "started_at", LocalDateTime.now().minusHours(1)));
            experience.setCompletedAt(parseDateTime(experienceData, "completed_at", LocalDateTime.now()));
            experience.setDurationMinutes(calculateDuration(experience.getStartedAt(), experience.getCompletedAt()));
            
            // 设置其他属性
            experience.setPrerequisites((String) experienceData.get("prerequisites"));
            experience.setAcquiredSkills((String) experienceData.get("acquired_skills"));
            experience.setApplicationCount(0);
            experience.setReinforcementCount(0);
            
            // 设置扩展属性
            Map<String, Object> metadata = createExperienceMetadata(experienceData);
            experience.setMetadata(jsonUtils.toJson(metadata));
            
            // 保存经验
            experience = learningExperienceRepository.save(experience);
            
            // 分析和关联相关经验
            analyzeAndLinkRelatedExperiences(experience);
            
            log.info("成功记录学习经验，ID: {}", experience.getId());
            return experience;
            
        } catch (Exception e) {
            log.error("记录学习经验失败", e);
            throw new RuntimeException("记录学习经验失败: " + e.getMessage());
        }
    }

    /**
     * 从历史经验中学习
     */
    @Transactional
    public LearningInsights learnFromHistory(Long lifeEntityId) {
        log.info("开始为生命体 {} 从历史经验中学习", lifeEntityId);
        
        try {
            List<LearningExperience> allExperiences = learningExperienceRepository.findByLifeEntityId(lifeEntityId);
            
            if (allExperiences.isEmpty()) {
                return new LearningInsights(lifeEntityId, "暂无历史经验可供学习");
            }
            
            LearningInsights insights = new LearningInsights(lifeEntityId);
            
            // 1. 分析成功模式
            List<SuccessPattern> successPatterns = analyzeSuccessPatterns(allExperiences);
            insights.setSuccessPatterns(successPatterns);
            
            // 2. 识别失败原因
            List<FailureReason> failureReasons = analyzeFailureReasons(allExperiences);
            insights.setFailureReasons(failureReasons);
            
            // 3. 发现学习趋势
            LearningTrend learningTrend = analyzeLearningTrend(allExperiences);
            insights.setLearningTrend(learningTrend);
            
            // 4. 生成改进建议
            List<String> recommendations = generateImprovementRecommendations(allExperiences);
            insights.setRecommendations(recommendations);
            
            // 5. 识别知识缺口
            List<String> knowledgeGaps = identifyKnowledgeGaps(allExperiences);
            insights.setKnowledgeGaps(knowledgeGaps);
            
            log.info("完成历史经验学习分析，生成 {} 个成功模式，{} 个失败原因，{} 条建议", 
                    successPatterns.size(), failureReasons.size(), recommendations.size());
            
            return insights;
            
        } catch (Exception e) {
            log.error("从历史经验学习失败", e);
            throw new RuntimeException("从历史经验学习失败: " + e.getMessage());
        }
    }

    /**
     * 应用经验到新情况
     */
    @Transactional
    public ExperienceApplication applyExperienceToSituation(Long lifeEntityId, Map<String, Object> situationData) {
        log.info("为生命体 {} 应用经验到新情况", lifeEntityId);
        
        try {
            // 分析当前情况
            SituationAnalysis situation = analyzeSituation(situationData);
            
            // 查找相关经验
            List<LearningExperience> relevantExperiences = findRelevantExperiences(lifeEntityId, situation);
            
            if (relevantExperiences.isEmpty()) {
                return new ExperienceApplication(lifeEntityId, "未找到相关经验", 0.0);
            }
            
            // 评估经验适用性
            List<ExperienceMatch> matches = evaluateExperienceApplicability(relevantExperiences, situation);
            
            // 选择最佳经验
            ExperienceMatch bestMatch = selectBestExperience(matches);
            
            // 适应经验到当前情况
            AdaptedExperience adaptedExperience = adaptExperienceToSituation(bestMatch, situation);
            
            // 更新经验使用统计
            updateExperienceUsageStats(bestMatch.getExperience());
            
            ExperienceApplication application = new ExperienceApplication(lifeEntityId);
            application.setAppliedExperience(bestMatch.getExperience());
            application.setAdaptedExperience(adaptedExperience);
            application.setConfidence(bestMatch.getMatchScore());
            application.setRecommendation(generateApplicationRecommendation(adaptedExperience));
            
            log.info("成功应用经验 {} 到新情况，置信度: {}", 
                    bestMatch.getExperience().getId(), bestMatch.getMatchScore());
            
            return application;
            
        } catch (Exception e) {
            log.error("应用经验到新情况失败", e);
            throw new RuntimeException("应用经验到新情况失败: " + e.getMessage());
        }
    }

    /**
     * 强化重要经验
     */
    @Transactional
    public void reinforceImportantExperiences(Long lifeEntityId) {
        log.info("开始强化生命体 {} 的重要经验", lifeEntityId);
        
        try {
            // 查找需要强化的经验
            List<LearningExperience> experiencesToReinforce = learningExperienceRepository
                    .findExperiencesNeedingReinforcement(lifeEntityId, 0.7, 0.6);
            
            for (LearningExperience experience : experiencesToReinforce) {
                reinforceExperience(experience);
            }
            
            log.info("完成经验强化，共强化 {} 个经验", experiencesToReinforce.size());
            
        } catch (Exception e) {
            log.error("强化重要经验失败", e);
        }
    }

    /**
     * 遗忘不重要的经验
     */
    @Transactional
    public void forgetUnimportantExperiences(Long lifeEntityId) {
        log.info("开始遗忘生命体 {} 的不重要经验", lifeEntityId);
        
        try {
            LocalDateTime threshold = LocalDateTime.now().minus(90, ChronoUnit.DAYS);
            List<LearningExperience> unusedExperiences = learningExperienceRepository
                    .findUnusedExperiences(lifeEntityId, threshold);
            
            int forgottenCount = 0;
            for (LearningExperience experience : unusedExperiences) {
                if (experience.getImportanceScore() < 0.3 && experience.getUsageFrequency() == 0) {
                    // 降低保持率，模拟遗忘
                    experience.setRetentionRate(experience.getRetentionRate() * 0.8);
                    learningExperienceRepository.save(experience);
                    forgottenCount++;
                }
            }
            
            log.info("完成经验遗忘，共遗忘 {} 个不重要经验", forgottenCount);
            
        } catch (Exception e) {
            log.error("遗忘不重要经验失败", e);
        }
    }

    // 私有辅助方法

    private ExperienceType parseExperienceType(Map<String, Object> data) {
        String typeStr = (String) data.get("experience_type");
        if (typeStr != null) {
            try {
                return ExperienceType.valueOf(typeStr.toUpperCase());
            } catch (IllegalArgumentException e) {
                log.warn("未知的经验类型: {}", typeStr);
            }
        }
        return ExperienceType.DECISION; // 默认类型
    }

    private LearningOutcome parseLearningOutcome(Map<String, Object> data) {
        String outcomeStr = (String) data.get("outcome");
        if (outcomeStr != null) {
            try {
                return LearningOutcome.valueOf(outcomeStr.toUpperCase());
            } catch (IllegalArgumentException e) {
                log.warn("未知的学习结果: {}", outcomeStr);
            }
        }
        return LearningOutcome.SUCCESS; // 默认结果
    }

    private Double parseDouble(Map<String, Object> data, String key, Double defaultValue) {
        Object value = data.get(key);
        if (value instanceof Number) {
            return ((Number) value).doubleValue();
        }
        return defaultValue;
    }

    private Integer parseInt(Map<String, Object> data, String key, Integer defaultValue) {
        Object value = data.get(key);
        if (value instanceof Number) {
            return ((Number) value).intValue();
        }
        return defaultValue;
    }

    private LocalDateTime parseDateTime(Map<String, Object> data, String key, LocalDateTime defaultValue) {
        Object value = data.get(key);
        if (value instanceof LocalDateTime) {
            return (LocalDateTime) value;
        }
        return defaultValue;
    }

    private Integer calculateDuration(LocalDateTime start, LocalDateTime end) {
        if (start != null && end != null) {
            return (int) ChronoUnit.MINUTES.between(start, end);
        }
        return null;
    }

    private Map<String, Object> createExperienceMetadata(Map<String, Object> experienceData) {
        Map<String, Object> metadata = new HashMap<>();
        metadata.put("source", "experience_learning_service");
        metadata.put("created_at", LocalDateTime.now());
        metadata.put("original_data_keys", experienceData.keySet());
        return metadata;
    }

    private void analyzeAndLinkRelatedExperiences(LearningExperience experience) {
        // 查找相似的经验
        List<LearningExperience> similarExperiences = learningExperienceRepository
                .findSimilarExperiences(
                        experience.getLifeEntityId(),
                        experience.getExperienceType(),
                        Math.max(1, experience.getDifficultyLevel() - 2),
                        Math.min(10, experience.getDifficultyLevel() + 2)
                );
        
        if (!similarExperiences.isEmpty()) {
            List<String> relatedIds = similarExperiences.stream()
                    .map(e -> e.getId().toString())
                    .limit(5)
                    .collect(Collectors.toList());
            
            experience.setRelatedExperienceIds(String.join(",", relatedIds));
            learningExperienceRepository.save(experience);
        }
    }

    private List<SuccessPattern> analyzeSuccessPatterns(List<LearningExperience> experiences) {
        List<SuccessPattern> patterns = new ArrayList<>();
        
        // 按经验类型分组分析成功模式
        Map<ExperienceType, List<LearningExperience>> byType = experiences.stream()
                .filter(e -> e.getOutcome() == LearningOutcome.SUCCESS || e.getOutcome() == LearningOutcome.EXCEEDED_EXPECTATIONS)
                .collect(Collectors.groupingBy(LearningExperience::getExperienceType));
        
        for (Map.Entry<ExperienceType, List<LearningExperience>> entry : byType.entrySet()) {
            if (entry.getValue().size() >= 3) { // 至少3个成功案例才算模式
                SuccessPattern pattern = new SuccessPattern();
                pattern.setType(entry.getKey());
                pattern.setSuccessCount(entry.getValue().size());
                pattern.setAverageEfficiency(entry.getValue().stream()
                        .mapToDouble(LearningExperience::getEfficiency)
                        .average().orElse(0.0));
                pattern.setDescription(String.format("在%s类型的经验中表现良好", entry.getKey().getDescription()));
                patterns.add(pattern);
            }
        }
        
        return patterns;
    }

    private List<FailureReason> analyzeFailureReasons(List<LearningExperience> experiences) {
        List<FailureReason> reasons = new ArrayList<>();
        
        List<LearningExperience> failures = experiences.stream()
                .filter(e -> e.getOutcome() == LearningOutcome.FAILURE)
                .collect(Collectors.toList());
        
        if (!failures.isEmpty()) {
            // 分析失败的共同特征
            double avgDifficulty = failures.stream()
                    .mapToDouble(LearningExperience::getDifficultyLevel)
                    .average().orElse(0.0);
            
            if (avgDifficulty > 7) {
                FailureReason reason = new FailureReason();
                reason.setReason("高难度任务");
                reason.setCount(failures.size());
                reason.setDescription("在高难度任务中容易失败");
                reasons.add(reason);
            }
        }
        
        return reasons;
    }

    private LearningTrend analyzeLearningTrend(List<LearningExperience> experiences) {
        LearningTrend trend = new LearningTrend();
        
        if (experiences.size() < 2) {
            trend.setTrendDirection("insufficient_data");
            return trend;
        }
        
        // 按时间排序
        experiences.sort(Comparator.comparing(LearningExperience::getStartedAt));
        
        // 计算效率趋势
        List<Double> efficiencies = experiences.stream()
                .map(LearningExperience::getEfficiency)
                .collect(Collectors.toList());
        
        double firstHalfAvg = efficiencies.subList(0, efficiencies.size() / 2).stream()
                .mapToDouble(Double::doubleValue).average().orElse(0.0);
        double secondHalfAvg = efficiencies.subList(efficiencies.size() / 2, efficiencies.size()).stream()
                .mapToDouble(Double::doubleValue).average().orElse(0.0);
        
        if (secondHalfAvg > firstHalfAvg + 0.1) {
            trend.setTrendDirection("improving");
        } else if (secondHalfAvg < firstHalfAvg - 0.1) {
            trend.setTrendDirection("declining");
        } else {
            trend.setTrendDirection("stable");
        }
        
        trend.setEfficiencyChange(secondHalfAvg - firstHalfAvg);
        
        return trend;
    }

    private List<String> generateImprovementRecommendations(List<LearningExperience> experiences) {
        List<String> recommendations = new ArrayList<>();
        
        // 分析低效率的经验
        List<LearningExperience> lowEfficiency = experiences.stream()
                .filter(e -> e.getEfficiency() < 0.5)
                .collect(Collectors.toList());
        
        if (!lowEfficiency.isEmpty()) {
            recommendations.add("关注提高学习效率，当前有" + lowEfficiency.size() + "个低效率经验");
        }
        
        // 分析保持率
        double avgRetention = experiences.stream()
                .mapToDouble(LearningExperience::getRetentionRate)
                .average().orElse(0.0);
        
        if (avgRetention < 0.6) {
            recommendations.add("加强知识巩固，当前平均保持率为" + String.format("%.2f", avgRetention));
        }
        
        return recommendations;
    }

    private List<String> identifyKnowledgeGaps(List<LearningExperience> experiences) {
        List<String> gaps = new ArrayList<>();
        
        // 分析经验类型的分布
        Map<ExperienceType, Long> typeCount = experiences.stream()
                .collect(Collectors.groupingBy(LearningExperience::getExperienceType, Collectors.counting()));
        
        // 检查是否缺少某些类型的经验
        for (ExperienceType type : ExperienceType.values()) {
            if (typeCount.getOrDefault(type, 0L) == 0) {
                gaps.add("缺少" + type.getDescription() + "类型的经验");
            }
        }
        
        return gaps;
    }

    private SituationAnalysis analyzeSituation(Map<String, Object> situationData) {
        SituationAnalysis analysis = new SituationAnalysis();
        analysis.setType((String) situationData.get("type"));
        analysis.setComplexity(parseDouble(situationData, "complexity", 0.5));
        analysis.setUrgency(parseDouble(situationData, "urgency", 0.5));
        analysis.setContext((String) situationData.get("context"));
        analysis.setRequiredSkills((String) situationData.get("required_skills"));
        return analysis;
    }

    private List<LearningExperience> findRelevantExperiences(Long lifeEntityId, SituationAnalysis situation) {
        // 根据情况类型查找相关经验
        ExperienceType relevantType = mapSituationToExperienceType(situation.getType());
        return learningExperienceRepository.findByLifeEntityIdAndExperienceType(lifeEntityId, relevantType);
    }

    private ExperienceType mapSituationToExperienceType(String situationType) {
        if (situationType == null) return ExperienceType.DECISION;
        
        switch (situationType.toLowerCase()) {
            case "decision": return ExperienceType.DECISION;
            case "collaboration": return ExperienceType.COLLABORATION;
            case "problem": return ExperienceType.PROBLEM_SOLVING;
            case "innovation": return ExperienceType.INNOVATION;
            default: return ExperienceType.DECISION;
        }
    }

    private List<ExperienceMatch> evaluateExperienceApplicability(List<LearningExperience> experiences, SituationAnalysis situation) {
        return experiences.stream()
                .map(exp -> {
                    double matchScore = calculateMatchScore(exp, situation);
                    return new ExperienceMatch(exp, matchScore);
                })
                .filter(match -> match.getMatchScore() > 0.3) // 过滤低匹配度的经验
                .sorted(Comparator.comparing(ExperienceMatch::getMatchScore).reversed())
                .collect(Collectors.toList());
    }

    private double calculateMatchScore(LearningExperience experience, SituationAnalysis situation) {
        double score = 0.0;
        
        // 基于成功率
        if (experience.getOutcome() == LearningOutcome.SUCCESS) {
            score += 0.3;
        }
        
        // 基于效率
        score += experience.getEfficiency() * 0.2;
        
        // 基于保持率
        score += experience.getRetentionRate() * 0.2;
        
        // 基于重要性
        score += experience.getImportanceScore() * 0.1;
        
        // 基于使用频率
        score += Math.min(experience.getApplicationCount() / 10.0, 0.2);
        
        return Math.min(score, 1.0);
    }

    private ExperienceMatch selectBestExperience(List<ExperienceMatch> matches) {
        return matches.isEmpty() ? null : matches.get(0);
    }

    private AdaptedExperience adaptExperienceToSituation(ExperienceMatch match, SituationAnalysis situation) {
        AdaptedExperience adapted = new AdaptedExperience();
        adapted.setOriginalExperience(match.getExperience());
        adapted.setAdaptationScore(match.getMatchScore());
        adapted.setAdaptedContent(generateAdaptedContent(match.getExperience(), situation));
        adapted.setConfidenceLevel(match.getMatchScore());
        return adapted;
    }

    private String generateAdaptedContent(LearningExperience experience, SituationAnalysis situation) {
        return String.format("基于经验'%s'，在当前情况下建议：%s", 
                experience.getTitle(), 
                experience.getLearningContent());
    }

    private void updateExperienceUsageStats(LearningExperience experience) {
        experience.setApplicationCount(experience.getApplicationCount() + 1);
        experience.setLastAppliedAt(LocalDateTime.now());
        learningExperienceRepository.save(experience);
    }

    private String generateApplicationRecommendation(AdaptedExperience adaptedExperience) {
        return String.format("建议应用此经验，置信度: %.2f", adaptedExperience.getConfidenceLevel());
    }

    private void reinforceExperience(LearningExperience experience) {
        // 提高保持率
        experience.setRetentionRate(Math.min(1.0, experience.getRetentionRate() * 1.1));
        experience.setReinforcementCount(experience.getReinforcementCount() + 1);
        learningExperienceRepository.save(experience);
    }

    // 内部数据类
    public static class LearningInsights {
        private Long lifeEntityId;
        private String summary;
        private List<SuccessPattern> successPatterns = new ArrayList<>();
        private List<FailureReason> failureReasons = new ArrayList<>();
        private LearningTrend learningTrend;
        private List<String> recommendations = new ArrayList<>();
        private List<String> knowledgeGaps = new ArrayList<>();

        public LearningInsights(Long lifeEntityId) {
            this.lifeEntityId = lifeEntityId;
        }

        public LearningInsights(Long lifeEntityId, String summary) {
            this.lifeEntityId = lifeEntityId;
            this.summary = summary;
        }

        // getters and setters
        public Long getLifeEntityId() { return lifeEntityId; }
        public void setLifeEntityId(Long lifeEntityId) { this.lifeEntityId = lifeEntityId; }
        public String getSummary() { return summary; }
        public void setSummary(String summary) { this.summary = summary; }
        public List<SuccessPattern> getSuccessPatterns() { return successPatterns; }
        public void setSuccessPatterns(List<SuccessPattern> successPatterns) { this.successPatterns = successPatterns; }
        public List<FailureReason> getFailureReasons() { return failureReasons; }
        public void setFailureReasons(List<FailureReason> failureReasons) { this.failureReasons = failureReasons; }
        public LearningTrend getLearningTrend() { return learningTrend; }
        public void setLearningTrend(LearningTrend learningTrend) { this.learningTrend = learningTrend; }
        public List<String> getRecommendations() { return recommendations; }
        public void setRecommendations(List<String> recommendations) { this.recommendations = recommendations; }
        public List<String> getKnowledgeGaps() { return knowledgeGaps; }
        public void setKnowledgeGaps(List<String> knowledgeGaps) { this.knowledgeGaps = knowledgeGaps; }
    }

    public static class SuccessPattern {
        private ExperienceType type;
        private int successCount;
        private double averageEfficiency;
        private String description;

        // getters and setters
        public ExperienceType getType() { return type; }
        public void setType(ExperienceType type) { this.type = type; }
        public int getSuccessCount() { return successCount; }
        public void setSuccessCount(int successCount) { this.successCount = successCount; }
        public double getAverageEfficiency() { return averageEfficiency; }
        public void setAverageEfficiency(double averageEfficiency) { this.averageEfficiency = averageEfficiency; }
        public String getDescription() { return description; }
        public void setDescription(String description) { this.description = description; }
    }

    public static class FailureReason {
        private String reason;
        private int count;
        private String description;

        // getters and setters
        public String getReason() { return reason; }
        public void setReason(String reason) { this.reason = reason; }
        public int getCount() { return count; }
        public void setCount(int count) { this.count = count; }
        public String getDescription() { return description; }
        public void setDescription(String description) { this.description = description; }
    }

    public static class LearningTrend {
        private String trendDirection;
        private double efficiencyChange;

        // getters and setters
        public String getTrendDirection() { return trendDirection; }
        public void setTrendDirection(String trendDirection) { this.trendDirection = trendDirection; }
        public double getEfficiencyChange() { return efficiencyChange; }
        public void setEfficiencyChange(double efficiencyChange) { this.efficiencyChange = efficiencyChange; }
    }

    public static class ExperienceApplication {
        private Long lifeEntityId;
        private String message;
        private Double confidence;
        private LearningExperience appliedExperience;
        private AdaptedExperience adaptedExperience;
        private String recommendation;

        public ExperienceApplication(Long lifeEntityId) {
            this.lifeEntityId = lifeEntityId;
        }

        public ExperienceApplication(Long lifeEntityId, String message, Double confidence) {
            this.lifeEntityId = lifeEntityId;
            this.message = message;
            this.confidence = confidence;
        }

        // getters and setters
        public Long getLifeEntityId() { return lifeEntityId; }
        public void setLifeEntityId(Long lifeEntityId) { this.lifeEntityId = lifeEntityId; }
        public String getMessage() { return message; }
        public void setMessage(String message) { this.message = message; }
        public Double getConfidence() { return confidence; }
        public void setConfidence(Double confidence) { this.confidence = confidence; }
        public LearningExperience getAppliedExperience() { return appliedExperience; }
        public void setAppliedExperience(LearningExperience appliedExperience) { this.appliedExperience = appliedExperience; }
        public AdaptedExperience getAdaptedExperience() { return adaptedExperience; }
        public void setAdaptedExperience(AdaptedExperience adaptedExperience) { this.adaptedExperience = adaptedExperience; }
        public String getRecommendation() { return recommendation; }
        public void setRecommendation(String recommendation) { this.recommendation = recommendation; }
    }

    public static class SituationAnalysis {
        private String type;
        private Double complexity;
        private Double urgency;
        private String context;
        private String requiredSkills;

        // getters and setters
        public String getType() { return type; }
        public void setType(String type) { this.type = type; }
        public Double getComplexity() { return complexity; }
        public void setComplexity(Double complexity) { this.complexity = complexity; }
        public Double getUrgency() { return urgency; }
        public void setUrgency(Double urgency) { this.urgency = urgency; }
        public String getContext() { return context; }
        public void setContext(String context) { this.context = context; }
        public String getRequiredSkills() { return requiredSkills; }
        public void setRequiredSkills(String requiredSkills) { this.requiredSkills = requiredSkills; }
    }

    public static class ExperienceMatch {
        private LearningExperience experience;
        private Double matchScore;

        public ExperienceMatch(LearningExperience experience, Double matchScore) {
            this.experience = experience;
            this.matchScore = matchScore;
        }

        // getters and setters
        public LearningExperience getExperience() { return experience; }
        public void setExperience(LearningExperience experience) { this.experience = experience; }
        public Double getMatchScore() { return matchScore; }
        public void setMatchScore(Double matchScore) { this.matchScore = matchScore; }
    }

    public static class AdaptedExperience {
        private LearningExperience originalExperience;
        private Double adaptationScore;
        private String adaptedContent;
        private Double confidenceLevel;

        // getters and setters
        public LearningExperience getOriginalExperience() { return originalExperience; }
        public void setOriginalExperience(LearningExperience originalExperience) { this.originalExperience = originalExperience; }
        public Double getAdaptationScore() { return adaptationScore; }
        public void setAdaptationScore(Double adaptationScore) { this.adaptationScore = adaptationScore; }
        public String getAdaptedContent() { return adaptedContent; }
        public void setAdaptedContent(String adaptedContent) { this.adaptedContent = adaptedContent; }
        public Double getConfidenceLevel() { return confidenceLevel; }
        public void setConfidenceLevel(Double confidenceLevel) { this.confidenceLevel = confidenceLevel; }
    }xperience; }
        public void setOriginalExperience(LearningExperience originalExperience) { this.originalExperience = originalExperience; }
        public Double getAdaptationScore() { return adaptationScore; }
        public void setAdaptationScore(Double adaptationScore) { this.adaptationScore = adaptationScore; }
        public String getAdaptedContent() { return adaptedContent; }
        public void setAdaptedContent(String adaptedContent) { this.adaptedContent = adaptedContent; }
        public Double getConfidenceLevel() { return confidenceLevel; }
        public void setConfidenceLevel(Double confidenceLevel) { this.confidenceLevel = confidenceLevel; }
    }
}